Fase 1 · Planejamento e design
MyImobee: a vitrine digital do estoque da imobiliária.
Plataforma SaaS multi-tenant para imobiliárias e corretores regionais: portal público rápido e indexável, painel administrativo e cadastro assistido por IA com revisão humana obrigatória. Este documento cobre a arquitetura, o banco, os fluxos, o mapa de telas e as estratégias de autenticação, isolamento, IA e imagens. As telas estão no protótipo navegável.
1. Arquitetura proposta
Um único código Next.js serve os três frontends (portal, painel, master) com separação por rota e por permissão. Tudo que exige chave ou privilégio roda no servidor. O banco é a fonte da verdade e o isolamento entre imobiliárias é garantido no próprio Postgres.
host → agency_domains → agency_id · cache de páginas públicas · rate limitingagency_id e perfilapp/(portal), app/(painel), app/(master), lib/domain, supabase/migrations, supabase/functions.2. Estrutura inicial do banco
Toda tabela de negócio carrega agency_id. Chaves UUID, created_at/updated_at em todas, exclusão lógica onde a URL precisa sobreviver.
{{ t.name }}{{ t.tag }}property_status (rascunho, publicado, reservado, vendido, alugado, inativo) · purpose (venda, aluguel) · role (admin, imobiliaria, corretor) · badge (destaque, novidade, oportunidade, exclusivo). Código do imóvel: sequência por tenant com prefixo configurável (IMB-1024), índice único (agency_id, code) e busca por código no portal.3. Fluxos de usuário
4. Mapa de telas e URLs
{{ i.url }}{{ i.label }}5. Componentes do design system
Fundação: tema escuro de baixa saturação, Inter peso 500 nos títulos, raio de 8px, acento usado como linha e brilho — não como preenchimento. Botão principal com contorno, foco visível no acento, fotos grandes.
6. Autenticação e perfis
- Supabase Auth com e-mail e senha, link mágico e Google. Sessão em cookie httpOnly, lida no servidor (SSR).
- Um Custom Access Token Hook injeta no JWT o
agency_idativo e orolevindos dememberships. Um usuário pode pertencer a mais de uma imobiliária e alternar. - Perfis: admin (MyImobee, acesso global), imobiliaria (tudo do próprio tenant), corretor (cria e edita os próprios imóveis e leads). Permissões finas em
role_permissions, prontas para novos níveis. - Master com MFA obrigatório. “Acessar painel” de uma imobiliária gera sessão de suporte temporária e registrada em
audit_logs. - Favoritos começam em
localStorage; com conta de visitante, sincronizam na tabelafavorites(merge no primeiro login).
7. Estratégia multi-tenant
- Banco compartilhado, isolamento por linha:
agency_idem todas as tabelas de negócio + Row Level Security em todas elas. Uma imobiliária nunca lê dados de outra, nem se a API tiver um bug. - Resolução pelo domínio: o middleware lê o
host(caririprime.myimobee.com.brouwww.caririprime.com.br), consultaagency_domains(em cache) e injeta o tenant no contexto da requisição.myimobee.com.bré o portal agregado. - Storage: caminhos
{agency_id}/{property_id}/{media_id}.webpcom políticas que conferem oagency_iddo JWT. - Chave service_role só em Edge Functions e jobs; o navegador usa apenas a chave anônima, sempre sob RLS.
- Limites do plano aplicados no servidor (imóveis, usuários, armazenamento, operações de IA, destaques, domínio próprio).
create function auth.agency_id() returns uuid language sql stable as $$
select nullif(auth.jwt() ->> 'agency_id', '')::uuid $$;
alter table properties enable row level security;
-- leitura pública: somente anúncios visíveis
create policy "portal lê anúncios visíveis" on properties for select
using (status in ('publicado','reservado','vendido','alugado'));
-- equipe da imobiliária: tudo do próprio tenant
create policy "equipe gerencia o tenant" on properties for all
using (agency_id = auth.agency_id())
with check (agency_id = auth.agency_id());
-- corretor: só edita o que é dele
create policy "corretor edita os próprios" on properties for update
using (agency_id = auth.agency_id()
and (auth.jwt() ->> 'role' <> 'corretor' or broker_id = auth.uid()));
8. Fluxo do cadastro com IA
- Entrada: texto livre, fotos (até 40) e, na próxima fase, PDF/Word/planilha (extração de texto no servidor antes da IA).
- Extração estruturada: a IA devolve JSON validado por schema; cada campo vem com
source(texto, foto ou nulo). Campo ausente =null→ “Não informado”. - Inferência visual nunca vira fato: aparece como “Possível característica — confirmar antes de publicar” e só entra no anúncio se o usuário confirmar.
- Descrição (Objetivo, Comercial, Premium, SEO) e SEO são gerados só a partir dos campos confirmados.
- Revisão humana obrigatória: o resultado é salvo como rascunho; a publicação exige clique em “Publicar imóvel” e confirmação explícita.
- Rastreio e custo: cada chamada grava
ai_jobs(tenant, tipo, tokens, custo, duração, erro). Limite mensal por plano e rate limit por usuário. - Falha: sem resposta da IA, o sistema faz leitura básica local e marca tudo para revisão — o corretor nunca fica bloqueado.
9. Fluxo de upload de imagens
- Pré-processamento no navegador (redimensiona para 1600px e converte para WebP) reduz o upload em 80–95% em redes móveis — já funcionando no protótipo.
- Upload direto ao Storage por URL assinada; o servidor valida tipo real pelos magic bytes, tamanho (15 MB) e quantidade por imóvel.
- Worker gera variantes 1600/960/480/320 em AVIF e WebP, remove EXIF/GPS, calcula blurhash (placeholder), hash perceptual (duplicadas) e nota de nitidez (baixa qualidade).
property_mediaguarda ordem, principal, legenda, alt e ambiente. Entrega por CDN comsrcset, lazy loading e cache imutável.
10. Integrações
| Integração | Agora | Depois |
|---|---|---|
| {{ i.n }} | {{ i.now }} | {{ i.later }} |
11. SEO e performance
- URLs amigáveis estáveis:
/imovel/casa-3-quartos-salesianos-juazeiro-do-norte/1024. O número final é a chave; se o slug mudar, 301 para o novo. - Páginas indexáveis de cidade, bairro e tipo:
/imoveis/juazeiro-do-norte-ce,/imoveis/juazeiro-do-norte-ce/casas, com texto local e links internos. - Gerados automaticamente: title, meta description, Open Graph (imagem principal 1200×630), canonical, breadcrumb (BreadcrumbList) e JSON-LD
RealEstateListing+Offer. - Vendido/alugado mantém a URL no ar com o aviso e imóveis semelhantes — preserva o SEO e aproveita o tráfego.
sitemap.xmlerobots.txtpor tenant; ISR com revalidação ao publicar/editar.- Meta: LCP abaixo de 2,5 s em 4G, CLS abaixo de 0,1. Imagem hero com prioridade, restante lazy, fontes com
display=swap, JS mínimo no portal.